SPB Git

Repository Public

route.ts 2.4 KB 41 lines typescript

1// Vrai-Prix — méthode du coût : fiche d'un assemblage (composition, prix, main-d'œuvre, sources, variations régionales, historique).2import { NextRequest, NextResponse } from "next/server";3import { buildContext, loadLocations } from "@/lib/cost/catalog";4import { assemblyUnitCost } from "@/lib/cost/engine";5import { cached } from "@/lib/cost/cache";67export const runtime = "nodejs";89export async function GET(req: NextRequest, { params }: { params: Promise<{ code: string }> }) {10  const { code: raw } = await params;11  const code = decodeURIComponent(raw);12  const loc = req.nextUrl.searchParams.get("location") ?? "QC-MTL";13  try {14    const data = cached(`assembly:${code}:${loc}`, 10 * 60_000, () => {15      const ctx = buildContext({ locationCode: loc });16      const a = ctx.assemblies.get(code);17      if (!a) return null;18      const unit = assemblyUnitCost(a, ctx);19      // variations régionales (facteurs appliqués au coût direct par unité)20      const regional = loadLocations().map((l) => ({ code: l.code, nameFr: l.nameFr, nameEn: l.nameEn, direct: Math.round(100 * (unit.material * l.materialFactor + unit.labour * l.labourFactor + unit.equipment * l.equipmentFactor)) / 100, materialFactor: l.materialFactor, labourFactor: l.labourFactor, equipmentFactor: l.equipmentFactor }));21      // historique : coût unitaire recalculé aux 8 derniers trimestres avec les prix de l'époque22      const history: { date: string; direct: number; material: number; labour: number; equipment: number; kind: string }[] = [];23      const now = new Date(ctx.asOf);24      for (let k = 7; k >= 0; k--) {25        const d = new Date(now);26        d.setMonth(d.getMonth() - 3 * k);27        const asOf = d.toISOString().slice(0, 10);28        const c2 = buildContext({ asOf, locationCode: loc });29        const u2 = assemblyUnitCost(a, c2);30        const kinds = new Set(u2.components.map((c) => c.provenance.kind));31        history.push({ date: asOf, direct: u2.direct, material: u2.material, labour: u2.labour, equipment: u2.equipment, kind: kinds.has("observed") || kinds.has("official") ? "observed" : kinds.has("indexed") ? "indexed" : "reference" });32      }33      return { asOf: ctx.asOf, location: ctx.location, assembly: a, unit, regional, history };34    });35    if (!data) return NextResponse.json({ error: "assemblage introuvable" }, { status: 404 });36    return NextResponse.json(data);37  } catch (e) {38    return NextResponse.json({ error: (e as Error).message }, { status: 500 });39  }40}41
Files main
Menu

Theme